// 重要的事情说三遍：本人对Arduino IDE实在不习惯，所以没有进行文件分类引用，本代码只实现基本了功能，所以不要吐槽！
// 重要的事情说三遍：本人对Arduino IDE实在不习惯，所以没有进行文件分类引用，本代码只实现基本了功能，所以不要吐槽！
// 重要的事情说三遍：本人对Arduino IDE实在不习惯，所以没有进行文件分类引用，本代码只实现基本了功能，所以不要吐槽！

// 本程序参考均为百度，具体出处我也忘了！

#include "Freenove_WS2812_Lib_for_ESP32.h"

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
//UART1
#include "driver/uart.h"
#include <Wire.h>

BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;

uint8_t txValue[3];
uint8_t ConnectionFlag = 0;  //连接状态

#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"  // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

#define LEDS_COUNT 8
#define LEDS_PIN 3
#define CHANNEL 0
uint8_t Tx1_buffer[32];
uint8_t Tx1_len;

uint8_t led_Set0 = 0;
uint8_t led_Set1 = 0;
uint8_t led_Set2 = 0;
uint8_t led_Set3 = 0;
uint8_t LedCnt = 0;
uint16_t led_cnt = 0;

Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB);

class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer *pServer) {
    deviceConnected = true;
  };

  void onDisconnect(BLEServer *pServer) {
    deviceConnected = false;
  }
};
String resStr;
String chipId;

int8_t RC_SpeedData = 0;
int8_t RC_YawData = 0;
uint8_t BrakeFlag = 0;
uint8_t BrakeCnt = 0;

class MyCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    std::string rxValue = pCharacteristic->getValue();

    if (rxValue.length() > 0) {
      Tx1_len = rxValue.length();
      memcpy((void *)Tx1_buffer, pCharacteristic->getData(), Tx1_len);

      if (Tx1_buffer[0] == 0x20 && Tx1_buffer[1] == 0x0f && Tx1_buffer[14] == 0x66) {
        if (Tx1_buffer[2] == 1) led_Set0 = 1;
        else led_Set0 = 0;
        RC_SpeedData = Tx1_buffer[5];
        if (RC_SpeedData < 10 && RC_SpeedData > -10) {
          if (BrakeFlag == 1) {
            BrakeFlag = 2;
            led_Set3 = 1;
          }
        } else {
          if (BrakeFlag == 0) {
            BrakeFlag = 1;
          } else if (BrakeFlag == 2) {
            BrakeFlag = 0;
            BrakeCnt = 0;
            led_Set3 = 0;
          }
        }

        RC_YawData = Tx1_buffer[4];
        if (RC_YawData < 25 && RC_YawData > -25) {
          RC_YawData = 0;
          led_Set2 = 0;
        } else {
          if (RC_YawData > 25) {
            if (led_Set2 == 0 || led_Set2 == 2) {
              led_Set2 = 1;  // 右转弯
              led_cnt = 100;
            }
          } else if (RC_YawData < -25) {
            if (led_Set2 == 0 || led_Set2 == 1) {
              led_Set2 = 2;  // 左转弯
              led_cnt = 100;
            }
          }
        }
      }
    }
  }
};


#define RX1_BUF_SIZE (1024)
#define TX1_BUF_SIZE (512)
#define TXD1_PIN (GPIO_NUM_0)
#define RXD1_PIN (GPIO_NUM_1)

uint8_t testData[8];

void uart1_init(void) {
  //串口配置结构体
  uart_config_t uart1_config;
  uart1_config.baud_rate = 115200 * 8;                //波特率
  uart1_config.data_bits = UART_DATA_8_BITS;          //数据位
  uart1_config.parity = UART_PARITY_DISABLE;          //校验位
  uart1_config.stop_bits = UART_STOP_BITS_1;          //停止位
  uart1_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;  //硬件流控
  uart_param_config(UART_NUM_1, &uart1_config);       //设置串口
  //IO映射-> T:IO12  R:IO13
  uart_set_pin(UART_NUM_1, TXD1_PIN, RXD1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  //注册串口服务即使能+设置缓存区大小
  uart_driver_install(UART_NUM_1, RX1_BUF_SIZE * 2, TX1_BUF_SIZE * 2, 0, NULL, 0);

  testData[0] = 1;
  testData[1] = 2;
  testData[2] = 3;
  testData[3] = 4;
  testData[4] = 5;
  testData[5] = 6;
  testData[6] = 7;
  testData[7] = 0;
}

void setup() {
  strip.begin();
  // Wire.begin(4,5,200000); // GPIO 200KHZ
  // setupCompass();
  strip.setBrightness(255);

  // strip.setLedColorData(5,10,10,10); // 后中间
  // strip.setLedColorData(6,10,10,10); // 后中间
  Serial.begin(115200);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(12, 1);
  digitalWrite(13, 0);
  chipId = String((uint32_t)ESP.getEfuseMac(), HEX);
  chipId.toUpperCase();
  //  chipid =ESP.getEfuseMac();
  //  Serial.printf("Chip id: %s\n", chipid.c_str());
  Serial.println(chipId);
  // Create the BLE Device
  BLEDevice::init("ShouGongFan");

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pTxCharacteristic = pService->createCharacteristic(
    CHARACTERISTIC_UUID_TX,
    BLECharacteristic::PROPERTY_NOTIFY);

  pTxCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
    CHARACTERISTIC_UUID_RX,
    BLECharacteristic::PROPERTY_WRITE);

  pRxCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
  uart1_init();
  txValue[0] = 1;
  txValue[1] = 2;
  txValue[2] = 3;

  uart_write_bytes(UART_NUM_1, (char *)testData, 8);
}


uint8_t led_bit = 0;
uint8_t led_flag = 0;
String readString;

uint8_t txlen = 0;
uint8_t txCnt = 0;

void loop() {

  if (BrakeFlag == 2) {
    if (++BrakeCnt >= 18) {
      BrakeFlag = 0;
      BrakeCnt = 0;
      led_Set3 = 0;
    }
  }

  // if(++txCnt >= 10)
  // {
  //   txCnt = 0;
  // txlen = uart_get_buffered_data_len(UART_NUM_1,4);

  int length = 0;
  ESP_ERROR_CHECK(uart_get_buffered_data_len(UART_NUM_1, (size_t *)&length));
  // length = uart_read_bytes(UART_NUM_1, txValue, length, 100);


  if (length >= 4) {
    // uart_write_bytes(UART_NUM_0, (char *)txValue, 4);
    // if(++txCnt >= 100)
    // {
    //   txCnt = 0;
    uart_read_bytes(UART_NUM_1, txValue, 4, portMAX_DELAY);  //读取数据
    if (led_Set0 == 0) {
      txValue[2] = 0;
    } else if (led_Set0 == 1) {
      txValue[2] = 1;
    }
    pTxCharacteristic->setValue(&txValue[0], 4);  // 发送
    pTxCharacteristic->notify();
    // }
  }
  // }

  if (++led_cnt >= 18) {
    led_cnt = 0;

    if (led_Set1 == 1) {
      if (led_bit == 0) {
        led_bit = 1;

        // strip.setLedColorData(3,10,10,0);
        // strip.setLedColorData(4,10,10,0);
        // strip.setLedColorData(0,10,10,0);
        // strip.setLedColorData(7,10,10,0);
      } else if (led_bit == 1) {
        led_bit = 0;
        // strip.setLedColorData(3,0,0,0);
        // strip.setLedColorData(4,0,0,0);
        // strip.setLedColorData(0,0,0,0);
        // strip.setLedColorData(7,0,0,0);
      }
    } else if (led_Set1 == 0) {
      if (led_Set2 == 0) {
        strip.setLedColorData(3, 0, 0, 0);
        strip.setLedColorData(4, 0, 0, 0);
        strip.setLedColorData(0, 0, 0, 0);
        strip.setLedColorData(7, 0, 0, 0);
      } else if (led_Set2 == 1) {
        if (led_bit == 0) {
          led_bit = 1;
          strip.setLedColorData(3, 50, 50, 0);
          strip.setLedColorData(4, 10, 10, 0);
        } else if (led_bit == 1) {
          led_bit = 0;
          strip.setLedColorData(3, 0, 0, 0);
          strip.setLedColorData(4, 0, 0, 0);
          strip.setLedColorData(0, 0, 0, 0);
          strip.setLedColorData(7, 0, 0, 0);
        }
      } else if (led_Set2 == 2) {
        if (led_bit == 0) {
          led_bit = 1;
          strip.setLedColorData(0, 50, 50, 0);
          strip.setLedColorData(7, 10, 10, 0);
        } else if (led_bit == 1) {
          led_bit = 0;
          strip.setLedColorData(3, 0, 0, 0);
          strip.setLedColorData(4, 0, 0, 0);
          strip.setLedColorData(0, 0, 0, 0);
          strip.setLedColorData(7, 0, 0, 0);
        }
      } else if (led_Set2 == 3) {
        // strip.setLedColorData(3,50,0,0);
        // strip.setLedColorData(4,50,0,0);
        // strip.setLedColorData(0,50,0,0);
        // strip.setLedColorData(7,50,0,0);
      }
    }

    if (led_Set3 == 0) {
      strip.setLedColorData(5, 0, 0, 0);
      strip.setLedColorData(6, 0, 0, 0);
    } else if (led_Set3 == 1) {
      strip.setLedColorData(5, 50, 0, 0);
      strip.setLedColorData(6, 50, 0, 0);
    }

    if (ConnectionFlag == 0) {
      if (led_flag == 0) {
        led_flag = 1;
        digitalWrite(12, 1);
      } else if (led_flag == 1) {
        led_flag = 0;
        digitalWrite(12, 0);
      }
    } else if (ConnectionFlag == 0) {
      digitalWrite(12, 0);
    }
  }
  if (led_Set0 == 1) {
    if (LedCnt < 100) LedCnt += 2;
    strip.setLedColorData(1, LedCnt, LedCnt, LedCnt);  // 前中间
    strip.setLedColorData(2, LedCnt, LedCnt, LedCnt);  // 前中间
  } else if (led_Set0 == 0) {
    if (LedCnt > 0) LedCnt -= 2;
    strip.setLedColorData(1, LedCnt, LedCnt, LedCnt);  // 前中间
    strip.setLedColorData(2, LedCnt, LedCnt, LedCnt);  // 前中间
  }
  strip.show();
  delay(20);

  if (deviceConnected)  // 设备连接成功
  {
    ConnectionFlag = 1;
    uart_write_bytes(UART_NUM_1, (char *)Tx1_buffer, Tx1_len);
  } else {
    ConnectionFlag = 0;
    Tx1_buffer[0] = 0x20;
    Tx1_buffer[1] = 0x0f;
    Tx1_buffer[4] = 0x00;
    Tx1_buffer[5] = 0x00;
    Tx1_buffer[14] = 0x66;
    uart_write_bytes(UART_NUM_1, (char *)Tx1_buffer, Tx1_len);
  }

  // Serial.println("RGB...");
  while (Serial.available() > 0) {
    if (deviceConnected)  // 设备连接成功
    {
      delay(3);
      readString += Serial.read();
      pTxCharacteristic->setValue(chipId.c_str());
      //      pTxCharacteristic->setValue((uint32_t)ESP.getEfuseMac());
      pTxCharacteristic->notify();
      // Serial.println(chipId);
    }
  }
  // disconnecting
  if (!deviceConnected && oldDeviceConnected) {
    delay(500);                   // give the bluetooth stack the chance to get things ready
    pServer->startAdvertising();  // restart advertising
    // Serial.println("start advertising");
    oldDeviceConnected = deviceConnected;
  }
  // connecting
  if (deviceConnected && !oldDeviceConnected) {
    // do stuff here on connecting
    oldDeviceConnected = deviceConnected;
  }
}
